package cn.cjlmonster.demo02.api;

import androidx.annotation.NonNull;

import com.google.gson.JsonObject;

import java.util.HashMap;
import java.util.Map;

import cn.cjlmonster.demo02.BuildConfig;
import cn.cjlmonster.demo02.api.callback.Callback;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * This project is Demo02
 * Created by cjl on 2021/11/23 10:45 下午.
 */
public class Request {

    private static class SingleHolder {
        private static final Request instance = new Request();
    }

    private final LinkGoCloudService service;

    private Request() {
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
        logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(logging)
                .build();
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BuildConfig.LINK_GO_CLOUD)
                .client(client)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        service = retrofit.create(LinkGoCloudService.class);
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public static class Builder implements Observer<Response<JsonObject>> {

        private String path;
        private final Map<String, Object> params;

        private Builder() {
            this.params = new HashMap<>();
        }

        public Builder setPath(String path) {
            if (path.startsWith("/")) path = path.substring(1);
            this.path = path;
            return this;
        }

        public Builder addParam(String key, Object value) {
            this.params.put(key, value);
            return this;
        }

        private Callback callBack;

        public void execute(@NonNull Callback callBack) {
            this.callBack = callBack;
            SingleHolder.instance.service.post(path, params)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(this);
        }

        @Override
        public void onSubscribe(@NonNull Disposable d) {
            callBack.onSubscribe(d);
        }

        @Override
        public void onNext(@NonNull Response<JsonObject> response) {
            try {
                if (response.isSuccessful()) {
                    if (response.body() != null) {
                        JsonObject jsonObject = response.body();
                        int status = jsonObject.get("status").getAsInt();
                        String msg = jsonObject.get("msg").getAsString();
                        String data = jsonObject.get("data").toString();
                        callBack.onResponse(status, msg, data);
                    } else {
                        callBack.onError(response.code(), new Exception("response' body is null"));
                    }
                } else {
                    callBack.onError(response.code(), new Exception(response.message()));
                }
            } catch (Exception e) {
                callBack.onError(-2, e);
            }
        }

        @Override
        public void onError(@NonNull Throwable e) {
            callBack.onError(-1, e);
        }

        @Override
        public void onComplete() {

        }
    }
}
